package com.airlines.crewassignment.service.assign.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.airlines.base.config.datasource.PrimaryDataSourceConfig;
import com.airlines.common.ListSortUtil;
import com.airlines.crewassignment.constant.CrewConstant;
import com.airlines.crewassignment.constant.LinkLineConstant;
import com.airlines.crewassignment.constant.PositionConstant;
import com.airlines.crewassignment.domain.Crew;
import com.airlines.crewassignment.domain.LinkLine;
import com.airlines.crewassignment.domain.Position;
import com.airlines.crewassignment.domain.Tech;
import com.airlines.crewassignment.entity.crew.CrewInfoForAssign;
import com.airlines.crewassignment.entity.linkline.LinkLineInfoForAssign;
import com.airlines.crewassignment.entity.linkline.PositionCrew;
import com.airlines.crewassignment.entity.ruleverification.RuleVerificationSummary;
import com.airlines.crewassignment.service.airport.AirportService;
import com.airlines.crewassignment.service.assign.PilotAssignService;
import com.airlines.crewassignment.service.crew.CrewService;
import com.airlines.crewassignment.service.dict.Select2Service;
import com.airlines.crewassignment.service.linkline.LinkLineService;
import com.airlines.crewassignment.service.linkline.PositionService;
import com.airlines.crewassignment.service.ruleverification.RuleVerificationService;

/**
 * @author xxxx
 * @date 2018年5月28日 
 * @description
 */
@Service
public class PilotAssignServiceImpl implements PilotAssignService {
	@Autowired
	private LinkLineService linkLineService;
	@Autowired
	private CrewService crewService;
	@Autowired
	private PositionService positionService;
	@Autowired
	private AirportService	airprotService;
	@Autowired
	private RuleVerificationService ruleVerificationService;
	@Autowired
	private Select2Service select2Service;

	
	@Override
	public List<LinkLineInfoForAssign> listLinkLineInfoForAssign(String dutyCode,Date flightDate) {
		List<LinkLineInfoForAssign> voList = new ArrayList<>();
		List<LinkLine> linkLineBaseList =   linkLineService.listLinkLineBase(dutyCode,flightDate);
		linkLineService.positionListInit(dutyCode,linkLineBaseList);
		//linkLineService.flightInfoListInit(dutyCode,flightDate, linkLineBaseList);
		//linkLineService.flightInfoSameTaskLoopList(dutyCode,linkLineBaseList);
		
		List<CrewInfoForAssign> crewList = crewService.listCrewInfoForAssignSimple(dutyCode,flightDate);
		DateTime flightDateStart = new DateTime(flightDate);
		DateTime flightDateEnd = flightDateStart.millisOfDay().withMaximumValue();
		List<RuleVerificationSummary> rvsList = ruleVerificationService.listRuleVerificationSummary(flightDateStart, flightDateEnd,dutyCode, null);
		
		//List<Select2> cityAbbrList = select2Service.getAirportCityAbbr();		
		for(LinkLine l : linkLineBaseList){
			LinkLineInfoForAssign vo = new LinkLineInfoForAssign();
			BeanUtils.copyProperties(l, vo);
//			String flightVoyage = 	airprotService.getShortCityLine(l.getFlightInfoSameTaskLoopList(),cityAbbrList);
//			vo.setLoopName(flightVoyage);
			vo.setLoopName(l.getLoopVoyage() == null ? l.getFlightVoyage() : l.getLoopVoyage() );
			vo.setDutyCode(dutyCode);
			
			
			
			String acType = l.getAcType();
			List<Position> positionList = l.getPositionList();
			ListSortUtil.sort(positionList, true, "serialNo");
			List<PositionCrew> captainList = new ArrayList<>();
			List<PositionCrew> fristCopilot  = new ArrayList<>();
			List<PositionCrew> secondCopilot  = new ArrayList<>();
			List<PositionCrew> cabin1 = new ArrayList<>(); //乘务长
			List<PositionCrew> cabin2 = new ArrayList<>();//两舱
			List<PositionCrew> cabin3 =new ArrayList<>();//后舱乘务员
			
			boolean confirmFlag = true;
			for(Position p : positionList){
				p.setLinkLine(null); // 防止循环引用
				String rankNo = p.getRankNo();
				int serialNo = p.getSerialNo();
				//飞行号位组装
				if(StringUtils.equals(dutyCode, CrewConstant.DUTY_F)){
					if(StringUtils.equals(rankNo, PositionConstant.RANK_NO_A001)|| StringUtils.equals(rankNo, PositionConstant.RANK_NO_B001) ){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						captainList.add(pc);
					}
					if(StringUtils.equals(rankNo, PositionConstant.RANK_NO_C001)){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						fristCopilot.add(pc);	
					}
					if(StringUtils.equals(rankNo, PositionConstant.RANK_NO_C002)){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						secondCopilot.add(pc);
					
					}
				}
				
				//客舱号位组装
				if(StringUtils.equals(dutyCode, CrewConstant.DUTY_C)){
					if(serialNo ==1 ){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						cabin1.add(pc);
					}
					if(serialNo ==2 ){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						cabin2.add(pc);	
					}
					if(serialNo >2){
						PositionCrew pc =this.initPositionCrew(crewList, p, acType);
						cabin3.add(pc);
					}
				}
				
				
				if(!StringUtils.equals(p.getConfirmFlag(), PositionConstant.CONFIRM_FLAG_Y)){
					confirmFlag = false;
				}
			}
		
			if(confirmFlag){
				vo.setConfirmFlagName(LinkLineConstant.CONFIRM_FLAG_NAME_Y);
			}else{
				vo.setConfirmFlagName(LinkLineConstant.CONFIRM_FLAG_NAME_N);
			}
			vo.setCaptainList(captainList);
			vo.setFristCopilot(fristCopilot);
			vo.setSecondCopilot(secondCopilot);
			vo.setCabin1(cabin1);
			vo.setCabin2(cabin2);
			vo.setCabin3(cabin3);
			
			
		
			
			//规则结果得分匹配
			List<PositionCrew> pcList = new ArrayList<>();
			pcList.addAll(captainList);
			pcList.addAll(fristCopilot);
			pcList.addAll(secondCopilot);
			pcList.addAll(cabin1);
			pcList.addAll(cabin2);
			pcList.addAll(cabin3);
//			for(PositionCrew pc : pcList){
//				for(RuleVerificationSummary rvs : rvsList){
//					if(StringUtils.equals(pc.getPosition().getDutyCode(),rvs.getDutyCode())
//							&& pc.getPosition().getFlightDate().equals(rvs.getFlightDate())
//							&& pc.getPosition().getCrewLinkLineNo().equals(rvs.getCrewLinkLineNo())
//							&& pc.getCrewInfoForAssign()!=null
//							&& StringUtils.equals(pc.getCrewInfoForAssign().getWorkcode(), rvs.getWorkcode())){
//						pc.setRuleVerificationSummary(rvs);
//					}
//							
//				}
//			}
			
			RuleVerificationSummary rvsForCrewLinkLine  = new RuleVerificationSummary();
			rvsForCrewLinkLine.setFlightDate(flightDate);
			rvsForCrewLinkLine.setDutyCode(dutyCode);
			rvsForCrewLinkLine.setCrewLinkLineNo(l.getCrewLinkLineNo());
			int hardSorce = 0;
			int waringSorce = 0;
		    int softSorce = 0;
			for(RuleVerificationSummary rvs : rvsList){
				if( l.getFlightDate().equals(rvs.getFlightDate()) 
						&& l.getCrewLinkLineNo().equals(rvs.getCrewLinkLineNo())
						&& StringUtils.equals(l.getDutyCode(), rvs.getDutyCode())){
					hardSorce += rvs.getHardSorce();
					waringSorce += rvs.getWaringSorce();
					softSorce += rvs.getSoftSorce();
				}
			}
			
			int verificationResultLevel = 0;
			if(hardSorce<0){
				verificationResultLevel = 2;
			}else if(waringSorce <0){
				verificationResultLevel = 1;
			}else{
				//
			}
			rvsForCrewLinkLine.setVerificationResultLevel(verificationResultLevel);
			rvsForCrewLinkLine.setHardSorce(hardSorce);
			rvsForCrewLinkLine.setWaringSorce(waringSorce);
			rvsForCrewLinkLine.setSoftSorce(softSorce);
			vo.setRuleVerificationSummary(rvsForCrewLinkLine);
			voList.add(vo);
		}
		
	
		
		return voList;
	}
	
	private PositionCrew initPositionCrew(List<CrewInfoForAssign> crewList,Position p,String acType){
		PositionCrew pc = new PositionCrew();
		pc.setCrewInfoForAssign(getCrew(crewList,p.getWorkcode(),acType));
		pc.setPosition(p);
		return pc;
	}
	
	private CrewInfoForAssign getCrew(List<CrewInfoForAssign>  allList,String workcode,String acType){
		for(CrewInfoForAssign c :allList){
			if(StringUtils.equals(c.getWorkcode(), workcode) && StringUtils.isNotBlank(c.getWorkcode())){
				
				//根据机型，筛选符合机型的排班授权
				for(Tech t :c.getTechZList()){
					if(StringUtils.equals(t.getAcType(), acType)){
						c.setTechZName(t.getTechName());
						c.setTechZLimit(t.getTechLimit());
					}
				}
				
				return c;
			}
		}
		
		return null;
	}

	@Transactional(transactionManager = PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public boolean save(List<LinkLineInfoForAssign> list) {
		Set<Date> dateSet = new HashSet<>();
		List<PositionCrew> pilotListALl = new ArrayList<>();
		for(LinkLineInfoForAssign la : list){
			 List<PositionCrew> captainList  = la.getCaptainList();
			 List<PositionCrew> airlineCaptainList = la.getAirlineCaptainList();
			 List<PositionCrew> fristCopilot =la.getFristCopilot();;
			 List<PositionCrew> secondCopilot = la.getSecondCopilot() ;
			 
			 pilotListALl.addAll(captainList);
			 pilotListALl.addAll(airlineCaptainList);
			 pilotListALl.addAll(fristCopilot);
			 pilotListALl.addAll(secondCopilot);
			 
			 dateSet.add(la.getFlightDate());
		}
		
		//判断是否可以保存
		for(Date flightDate : dateSet){
			boolean updateAbleFlag = positionService.updateAbleCheck(flightDate);
			if(!updateAbleFlag){
				return updateAbleFlag;
			}
		}
		

		//0.查询哪些是删除的号位
//		List<Position> deleteList = new  ArrayList<>();
//		for(Date flightDate : dateSet){
//			Position postionQuery = new Position();
//			postionQuery.setFlightDate(flightDate);
//			postionQuery.setDutyCode(CrewConstant.DUTY_F);
//			List<Position> tempList = positionService.listPosition(postionQuery);
//			for(Position inDb :  tempList){
//				boolean inDbFlag = false;
//				for(PositionCrew pc : pilotListALl){
//					if(inDb.getPositionId().equals(pc.getPosition().getPositionId())){
//						inDbFlag = true;
//					}
//				}
//				
//				if(!inDbFlag){
//					deleteList.add(inDb);
//				}
//			}
//		}
		
		
		//1.新增、修改操作
		for(PositionCrew pc : pilotListALl){
			Position p  = pc.getPosition();
			p.setAutoFlag(PositionConstant.AUTO_FLAG_H);
			positionService.saveOrUpdate(p);
		}
		
		//2.删除操作
//		for(Position p : deleteList){
//			positionService.deleteByPrimaryKey(p.getPositionId());
//		}
		
		return true;
	}

	@Override
	public boolean confirm(String dutyCode,Date flightDate) {
		boolean updateAbleFlag = positionService.updateAbleCheck(flightDate);
		if(!updateAbleFlag){
			return updateAbleFlag;
		}else{
			positionService.confirm(flightDate,dutyCode);
			return true;
		}
		
		
	}

	@Override
	public boolean save(Position position) {
		//判断是否可以保存		
		boolean updateAbleFlag = positionService.updateAbleCheck(position.getFlightDate());
		if(!updateAbleFlag){
			return updateAbleFlag;
		}
		
		Crew crew = crewService.getCrewByWorkcode(position.getWorkcode());
//		if(crew == null ){
//			return false;
//		}
		
		//连线相关信息初始化
		
		//其他属性初始化
		//position.setDutyCode(CrewConstant.DUTY_F);
		position.setAutoFlag(PositionConstant.AUTO_FLAG_H);
		position.setConfirmFlag(PositionConstant.CONFIRM_FLAG_N);
		position.setStatus(PositionConstant.STATUS_A);
		if(crew != null){
			position.setPCode(crew.getPCode());
		}
		
		if(position.getPositionId() == null && position.getSerialNo() == null){
			//是新增，则查询号位信息，并赋值
			Position query = new Position();
			query.setDutyCode(position.getDutyCode());
			query.setFlightDate(position.getFlightDate());
			query.setCrewLinkLineNo(position.getCrewLinkLineNo());
			
			List<Position> indbList = positionService.listPosition(query);
			List<Integer> serialNoHaveList = new ArrayList<>();
			for(Position p:indbList ){
				if(p.getSerialNo()!=null){
					serialNoHaveList.add(p.getSerialNo());
				}
			}
			
			int newSerialNo = positionService.getNewSerialNo(serialNoHaveList);
			
			position.setSerialNo(newSerialNo);
			
		}
		
		positionService.saveOrUpdate(position);
		
		return true;
	}
}
